/*********************************************************************************************************************
 * COPYRIGHT NOTICE
 * Copyright (c) 2018,逐飞科技
 * All rights reserved.
 * 技术讨论QQ群：	一群：179029047(已满)
 *					二群：244861897(已满)
 *					三群：824575535
 *
 * 以下所有内容版权均属逐飞科技所有，未经允许不得用于商业用途，
 * 欢迎各位使用并传播本程序，修改内容时必须保留逐飞科技的版权声明。
 *
 * @file			zf_gpio.c
 * @company			成都逐飞科技有限公司
 * @author			逐飞科技(QQ3184284598)
 * @version			查看doc内version文件 版本说明
 * @Software		IAR 8.3 or MDK 5.24
 * @Taobao			https://seekfree.taobao.com/
 * @date			2020-03-25
 * @note			本文件作为 LPC55S 系列芯片开源库外设文件
					提供 GPIO 外设驱动	
 ********************************************************************************************************************/

#include "zf_gpio.h"

//-------------------------------------------------------------------------------------------------------------------
//	@brief		端口管脚 GPIO 功能初始化
//	@param		group_index		管脚组别
//	@param		pin_index		管脚索引
//	@param		config			管脚配置
//	@param		dir				管脚方向
//	Sample usage:				zf_gpio_diy_init( GPIO0, PIN00, config, IOCON_PIO_DIR_OUT);
//-------------------------------------------------------------------------------------------------------------------
void zf_gpio_init (group_index_list group_index, pin_index_list pin_index, pin_param_t *config, pin_dir_list dir)
{	
	assert(config != NULL);
	IOCON->PIO[group_index][pin_index] = (config->pin_config & 0x000007FF);

	GPIO->DIR[group_index] |= ((dir && 0x00000001) << pin_index);							// 设置方向

	if(group_index == PIO1)
		CLOCK_EnableClock(kCLOCK_Gpio1);													// 开启 GPIO1 时钟
	else
		CLOCK_EnableClock(kCLOCK_Gpio0);													// 开启 GPIO0 时钟
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		端口管脚 GPIO 功能初始化
//	@param		group_index		管脚组别
//	@param		pin_index		管脚索引
//	@param		dir				管脚方向
//	Sample usage:				zf_gpio_init( GPIO0, PIN00, IOCON_PIO_DIR_OUT);
//-------------------------------------------------------------------------------------------------------------------
void zf_gpio_default_init (group_index_list group_index, pin_index_list pin_index, pin_dir_list dir)
{
	pin_param_t config;
	zf_gpio_get_default_config(&config);
	IOCON->PIO[group_index][pin_index] = (config.pin_config & 0x000007FF);

	GPIO->DIR[group_index] |= ((dir && 0x00000001) << pin_index);							// 设置方向

	if(group_index == PIO1)
		CLOCK_EnableClock(kCLOCK_Gpio1);													// 开启 GPIO1 时钟
	else
		CLOCK_EnableClock(kCLOCK_Gpio0);													// 开启 GPIO0 时钟
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		端口管脚 GPIO 功能获取默认配置
//	@param		config			管脚配置结构体
//	Sample usage:				zf_gpio_get_default_config(&config);
//-------------------------------------------------------------------------------------------------------------------
void zf_gpio_get_default_config (pin_param_t *config)
{
	config->param_bit.pin_param_func		= PIN_FUNC_0;									// 默认设置GPIO
	config->param_bit.pin_param_mode		= PIN_MODE_INACTIVE;							// 默认设置悬空
	config->param_bit.pin_param_slew		= PIN_SLEW_STANDARD;							// 默认设置标准速率
	config->param_bit.pin_param_invert		= PIN_INVERT_DISABLED;							// 默认设置禁止反相
	config->param_bit.pin_param_digimode	= PIN_DIGIMODE_ENABLED;							// 默认设置数字模式
	config->param_bit.pin_param_od			= PIN_OD_DISABLED;								// 默认设置禁止开漏
	config->param_bit.pin_param_asw			= PIN_ASW_DISABLED;								// 默认设置禁止模拟模式
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		端口管脚参数设置
//	@param		config			参数结构体
//	@param		pin_param_list	参数选项
//	@param		pin_config		参数值
//	Sample usage:				zf_pin_param_set( config, PIN_PARAM_MODE, IOCON_PIO_MODE_INACTIVE);
//-------------------------------------------------------------------------------------------------------------------
void zf_gpio_param_set (pin_param_t *config, pin_param_list param_index, uint32_t pin_config)
{
	switch(param_index)
	{
		case PIN_PARAM_FUNC:
			config->param_bit.pin_param_func		= (pin_func_list)pin_config;			// 设置引脚内部工作模式
			break;
		case PIN_PARAM_MODE:
			config->param_bit.pin_param_mode		= (pin_mode_list)pin_config;			// 设置引脚内部工作模式
			break;
		case PIN_PARAM_SLEW:
			config->param_bit.pin_param_slew		= (pin_slew_list)pin_config;			// 设置引脚速率
			break;
		case PIN_PARAM_INVERT:
			config->param_bit.pin_param_invert		= (pin_invert_list)pin_config;			// 设置反相设置
			break;
		case PIN_PARAM_DIGIMODE:
			config->param_bit.pin_param_digimode	= (pin_digimode_list)pin_config;		// 设置数字模式使能
			break;
		case PIN_PARAM_OD:
			config->param_bit.pin_param_od			= (pin_od_list)pin_config;				// 设置开漏模式使能
			break;
		case PIN_PARAM_ASW:
			config->param_bit.pin_param_asw			= (pin_asw_list)pin_config;				// 设置ADC输入使能 A type 引脚才有
			break;
		default:
			break;
	}
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		端口管脚 GPIO 功能下输出高低电平
//	@param		group_index		管脚组别
//	@param		pin_index		管脚索引
//	@param		level			输出高低电平
//	Sample usage:				zf_gpio_output(GPIO0, PIN00, ture);
//-------------------------------------------------------------------------------------------------------------------
void zf_gpio_output (group_index_list group_index, pin_index_list pin_index, bool level)
{
	if(level)
	{
		GPIO->SET[group_index] |= 															// 对应管脚置位寄存器
			(0x00000001 << pin_index);														// 对应管脚 bit 写 1 置位
	}
	else
	{
		GPIO->CLR[group_index] |=																// 对应管脚复位寄存器
			(0x00000001 << pin_index);														// 对应管脚 bit 写 1 复位
	}
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		端口管脚 GPIO 功能下翻转电平
//	@param		group_index		管脚组别
//	@param		pin_index		管脚索引
//	Sample usage:				zf_gpio_output_not(GPIO0, PIN00);
//-------------------------------------------------------------------------------------------------------------------
void zf_gpio_output_not (group_index_list group_index, pin_index_list pin_index)
{
	GPIO->NOT[group_index] |=																// 对应管脚翻转寄存器
		(0x00000001 << pin_index);															// 对应管脚 bit 写 1 翻转电平
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		IOT 主板上的 Arduino 端口管脚 GPIO 功能下读取电平
//	@param		group_index		管脚组别
//	@param		pin_index		管脚索引
//	Sample usage:				uint8_t pin_state = arduino_gpio_read( ARDUINO_PIN_D00);
//-------------------------------------------------------------------------------------------------------------------
bool zf_gpio_read (group_index_list group_index, pin_index_list pin_index)
{
	uint32_t data = GPIO->PIN[group_index];															// 读取对应组别状态寄存器
	return ((uint8_t)(data >> pin_index) & 0x00000001);											// 返回对应管脚状态
}
